

struct Material
{
	vec4 ambient;
	vec4 diffuse;
	vec4 specular;
	float shininess;
	vec4 emission;
};

struct Light
{
	vec4 ambient;
	vec4 diffuse;
	vec4 specular;
	vec4 position;
	float range;
};


vec4 calc_phong_lighting (Light light, Material material, vec3 position, vec3 normal)
{
  vec3 v_to_l	= light.position.xyz - position;
  float distance = length (v_to_l);
  v_to_l = normalize (v_to_l);

  vec3 v_to_e   = normalize (-position);

  vec4 color = light.ambient * material.ambient;

  // the diffuse term
  float dt = max(0.0, (dot (v_to_l, normal)));
  color += dt * light.diffuse * material.diffuse;

  // the specular terim
  vec3 half = normalize (v_to_e + v_to_l);
  float st = pow(max(0.0, min(1.0, dot(normal, half))), material.shininess);
  color += st * light.specular * material.specular;

  color += material.emission;

  float lightIntensity = clamp(1.0 - distance / light.range, 0.0, 1.0);
  color *= lightIntensity;

  return color;
}
